#include "../include/comm.h"
#include "../lvgl/lvgl.h"

#define CLIENT_PORT 8085

#define SERVER_ADDR "192.168.72.86"
#define SERVER_PORT 8100

#define EMOJI_RECV_FOLDER_PATH "/mnt/hgfs/share/chat_client_pc1/emoji_recv"

int tcpsock;
pthread_t pid_recv;
pthread_attr_t myattr;

char new_list_data[2048];
char new_msg_data[2048];
char new_file_data_head[2048];
char new_emoji_data_head[2048];
volatile bool list_need_update = false;
volatile bool msg_need_update = false;
volatile bool file_need_update = false;
volatile bool emoji_need_update = false;

char rbuf[2048];

void client_init()
{
    pthread_attr_init(&myattr);
    pthread_attr_setdetachstate(&myattr, PTHREAD_CREATE_DETACHED);

    struct sockaddr_in bindaddr;
    memset(&bindaddr, 0, sizeof(bindaddr));
    bindaddr.sin_family = AF_INET;
    bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    bindaddr.sin_port = htons(CLIENT_PORT);

    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
    serveraddr.sin_port = htons(SERVER_PORT);

    tcpsock = socket(AF_INET, SOCK_STREAM, 0);
    if(tcpsock == -1)
    {
        perror("创建套接字失败");
        exit(1);
    }

    int on = 1;
    setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    if(bind(tcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1)
    {
        perror("绑定失败");
        exit(1);
    }

    if(connect(tcpsock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)
    {
        perror("连接失败");
        exit(1);
    }
}

void get_comm_info(char *rbuf)
{
    int cnt = 0;
    int ret;
    char c;
    while(1)
    {
        ret = recv(tcpsock, &c, 1, 0);
        if(ret == 0)
        {
            printf("服务器退出了\n");
            exit(1);
        }
        else if(ret < 0)
        {
            fprintf(stderr, "接收服务器的信息失败:%s\n", strerror(errno));
            exit(1);
        }

        rbuf[cnt++] = c;
        if(c == '\n')
        {
            break;
        }
    }
    rbuf[cnt - 1] = '\0';
}

void *client_recv(void *arg)
{
    while(1)
    {
        memset(rbuf, 0, sizeof(rbuf));

        get_comm_info(rbuf);

        if(strncmp(rbuf, "getlist#", 8) == 0)
        {
            memset(new_list_data, 0, sizeof(new_list_data));
            strncpy(new_list_data, rbuf, sizeof(new_list_data));
            list_need_update = true;
        }
        else if(strncmp(rbuf, "chat#", 5) == 0)
        {
            memset(new_msg_data, 0, sizeof(new_msg_data));
            strncpy(new_msg_data, rbuf, sizeof(new_msg_data));
            msg_need_update = true;
        }
        else if(strncmp(rbuf, "sendfile#", 9) == 0)
        {
            memset(new_file_data_head, 0, sizeof(new_file_data_head));
            strncpy(new_file_data_head, rbuf, sizeof(new_file_data_head));

            char *p = strtok(rbuf, "#");
            p = strtok(NULL, "#");  // nickname
            p = strtok(NULL, "#");  // filename
            char filename[200] = {0};
            strncpy(filename, p, sizeof(filename));
            p = strtok(NULL, "#");  // filesize
            long filesize = atol(p);

            // 开始读取文件内容
            int fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0777);
            if(fd == -1)
            {
                fprintf(stderr, "打开%s失败:%s\n", filename, strerror(errno));
                exit(1);
            }

            long received = 0;
            int ret;
            while(received < filesize)
            {
                memset(rbuf, 0, sizeof(rbuf));
                ret = recv(tcpsock, rbuf, sizeof(rbuf), 0);
                if(ret == 0)
                {
                    printf("服务器退出了\n");
                    exit(1);
                }
                else if(ret < 0)
                {
                    perror("接收失败");
                }
                write(fd, rbuf, ret);
                received += ret;
            }
            close(fd);

            file_need_update = true;
        }
        else if(strncmp(rbuf, "emoji#", 6) == 0)
        {
            memset(new_emoji_data_head, 0, sizeof(new_emoji_data_head));
            strncpy(new_emoji_data_head, rbuf, sizeof(new_emoji_data_head));

            char *p = strtok(rbuf, "#");
            p = strtok(NULL, "#");  // nickname
            p = strtok(NULL, "#");  // emoji_name
            char emoji_path[512] = {0};
            const char *folder = EMOJI_RECV_FOLDER_PATH;
            snprintf(emoji_path, sizeof(emoji_path), "%s/%s", folder, p);
            p = strtok(NULL, "#");  // filesize
            long filesize = atol(p);

            // 开始读取文件内容
            int fd = open(emoji_path, O_CREAT | O_TRUNC | O_RDWR, 0777);
            if(fd == -1)
            {
                fprintf(stderr, "打开%s失败:%s\n", emoji_path, strerror(errno));
                exit(1);
            }

            long received = 0;
            int ret;
            while(received < filesize)
            {
                memset(rbuf, 0, sizeof(rbuf));
                ret = recv(tcpsock, rbuf, sizeof(rbuf), 0);
                if(ret == 0)
                {
                    printf("服务器退出了\n");
                    exit(1);
                }
                else if(ret < 0)
                {
                    perror("接收失败");
                }
                write(fd, rbuf, ret);
                received += ret;
            }
            close(fd);

            emoji_need_update = true;
        }
    }
    return NULL;
}
